package frame.laxcen.request;

import frame.laxcen.util.FrameWriter;
import frame.util.ByteArrayUtil;
import frame.util.ByteUtil;

// 读 6C 标签
public class Request_0010_10 implements IRequest {

    public final byte[] FrameBytes;

    public Request_0010_10(RequestTemplate template) {

        FrameWriter w = FrameWriter.instance(this.getClass());

        w.writeU8(template.AntennaFlag);

        w.writeU8(template.ReadMode);

        if(template.hasParam_0x01()) {

            w.writeP8s((byte) 0x01, ByteArrayUtil.concat(new byte[] {

                    template.Pid_0x01_0, template.Pid_0x01_1, template.Pid_0x01_2, template.Pid_0x01_3

            }, template.Pid_0x01_4_to_n));
        }

        if(template.hasParam_0x02()) {

            w.writeP16((byte) 0x02, ByteUtil.bytePairToShort(template.Pid_0x02_0, template.Pid_0x02_1));
        }

        if(template.hasParam_0x03()) {

            w.writeP8((byte) 0x03, template.Pid_0x03_0);

            w.writeU8(template.Pid_0x03_1);

            w.writeU8(template.Pid_0x03_2);
        }

        if(template.hasParam_0x04()) {

            w.writeP8((byte) 0x04, template.Pid_0x04_0);

            w.writeU8(template.Pid_0x04_1);

            w.writeU8(template.Pid_0x04_2);
        }

        if(template.hasParam_0x05()) {

            w.writeP32((byte) 0x05, template.Pid_0x05_0);

            w.writeU32(template.Pid_0x05_1);

            w.writeU32(template.Pid_0x05_2);

            w.writeU32(template.Pid_0x05_3);
        }

        this.FrameBytes = w.toByteArray();
    }

    @Override
    public byte[] getFrameBytes() {

        return FrameBytes;
    }

    public static class RequestTemplate {

        // 天线端口

        // bit位 0 - 4 对应 天线 1 - 4
        // 置 1 时为使用该天线

        public byte AntennaFlag = (byte) 0b0;

        // 读取模式

        // 0 -> 单次读
        // 1 -> 连续读

        public byte ReadMode = (byte) 0b0;

        // 读取的标签内容需要匹配的参数

        // 0 -> 匹配的数据区 1.EPC 2.TID 3. 用户数据区
        // 1 -> 地址 高8位
        // 2 -> 地址 低8位
        // 3 -> 需要匹配的数据的位长度 即bit长度 Byte是8位的
        // 4 to n -> 需要匹配的数据内容

        public Byte Pid_0x01_0;

        public Byte Pid_0x01_1;

        public Byte Pid_0x01_2;

        public Byte Pid_0x01_3;

        public byte[] Pid_0x01_4_to_n;

        // TID 读取参数

        // 0 -> 读取模式 0.自适应 1.定长
        // 1 -> 读取的字长 字 = 2字节 = 16bit

        public Byte Pid_0x02_0;

        public Byte Pid_0x02_1;

        // 用户数据区读取参数

        // 0 -> 地址 高8位
        // 1 -> 地址 低8位
        // 2 -> 读取字长 字 = 2字节 = 16bit

        public Byte Pid_0x03_0;

        public Byte Pid_0x03_1;

        public Byte Pid_0x03_2;

        // 保留区读取参数

        // 0 -> 地址 高8位
        // 1 -> 地址 低8位
        // 2 -> 读取字长 字 = 2字节 = 16bit

        public Byte Pid_0x04_0;

        public Byte Pid_0x04_1;

        public Byte Pid_0x04_2;

        // 标签访问密码

        // 四位 U32

        public Integer Pid_0x05_0;

        public Integer Pid_0x05_1;

        public Integer Pid_0x05_2;

        public Integer Pid_0x05_3;

        public boolean hasParam_0x01() {

            if(Pid_0x01_0 == null) return false;

            if(Pid_0x01_1 == null) return false;

            if(Pid_0x01_2 == null) return false;

            if(Pid_0x01_3 == null) return false;

            if(Pid_0x01_4_to_n == null) return false;

            return true;
        }

        public boolean hasParam_0x02() {

            if(Pid_0x02_0 == null) return false;

            if(Pid_0x02_1 == null) return false;

            return true;
        }

        public boolean hasParam_0x03() {

            if(Pid_0x03_0 == null) return false;

            if(Pid_0x03_1 == null) return false;

            if(Pid_0x03_2 == null) return false;

            return true;
        }

        public boolean hasParam_0x04() {

            if(Pid_0x04_0 == null) return false;

            if(Pid_0x04_1 == null) return false;

            if(Pid_0x04_2 == null) return false;

            return true;
        }

        public boolean hasParam_0x05() {

            if(Pid_0x05_0 == null) return false;

            if(Pid_0x05_1 == null) return false;

            if(Pid_0x05_2 == null) return false;

            if(Pid_0x05_3 == null) return false;

            return true;
        }

        // 配置使用天线1进行读操作
        public RequestTemplate useAntenna_1() {

            this.AntennaFlag |= 1;

            return this;
        }

        // 配置使用天线2进行读操作
        public RequestTemplate useAntenna_2() {

            this.AntennaFlag |= (1 << 1);

            return this;
        }

        // 配置使用天线3进行读操作
        public RequestTemplate useAntenna_3() {

            this.AntennaFlag |= (1 << 2);

            return this;
        }

        // 配置使用天线4进行读操作
        public RequestTemplate useAntenna_4() {

            this.AntennaFlag |= (1 << 3);

            return this;
        }

        // 默认配置 单次读 读TID 定长 6个字 读用户区 地址为0 8个字
        public RequestTemplate standerSingleRead() {

            // 单次读
            ReadMode = (byte) 0x00;

            // TID 定长读
            Pid_0x02_0 = (byte) 0x01;

            // TID读 6个字
            Pid_0x02_1 = (byte) 6;

            // 用户区地址 高8位
            Pid_0x03_0 = (byte) 0x00;

            // 用户区地址 低8位
            Pid_0x03_1 = (byte) 0x00;

            // 用户区读 8个字
            Pid_0x03_2 = (byte) 8;

            return this;
        }

        // 默认配置 连续读 读TID 定长 6个字 读用户区 地址为0 8个字
        public RequestTemplate standerSequenceRead() {

            // 单次读
            ReadMode = (byte) 0x01;

            // TID 定长读
            Pid_0x02_0 = (byte) 0x01;

            // TID读 6个字
            Pid_0x02_1 = (byte) 6;

            // 用户区地址 高8位
            Pid_0x03_0 = (byte) 0x00;

            // 用户区地址 低8位
            Pid_0x03_1 = (byte) 0x00;

            // 用户区读 8个字
            Pid_0x03_2 = (byte) 8;

            return this;
        }

        // 受限于通信协议 最多匹配255个bit位 所以只能匹配31个U8字符 (第32个U8的最后一个bit无法匹配到)
        // 对于UserData区的数据 同时由于Java的字符是16位的 所以强制要求仅使用Ascii字符 (因为Ascii字符集中的字符只占用低8位)
        // 使用时由被调用方执行转换操作 写入时仅保留低8位 作为传输数据 读取时会扩展成16位JavaChar作为返回数据
        // 这些操作对于调用方是透明的

        // 配置匹配读 匹配UserData 地址为0 16个Ascii字符
        public RequestTemplate matchAsciiUserData(String id) {

            id = id.substring(0, 16);

            Pid_0x01_0 = (byte) 0x03;

            Pid_0x01_1 = (byte) 0x00;

            Pid_0x01_2 = (byte) 0x00;

            Pid_0x01_4_to_n = ByteArrayUtil.asciiStringToBytes(id);

            Pid_0x01_3 = (byte) (Pid_0x01_4_to_n.length * 8);

            return this;
        }

        // TID的编码方式和UserData不同
        // TID的编码方式为 将每一个byte直接转化成对应的16进制数字 (范围为：00 - FF) 后拼接即可 (不足2位 前端补0)
        // 所以 6个字 = 12字节 = 24个U8 = 长度24的字符串 字符集为 [0-9a-f]
        // 使用时由调用方执行转换操作 读写转换方式不再赘述
        // 这些操作对于调用方是透明的

        // 配置匹配读 匹配TID 地址为0 24个Ascii字符
        public RequestTemplate matchTid(String id) {

            id = id.substring(0, 24);

            Pid_0x01_0 = (byte) 0x02;

            Pid_0x01_1 = (byte) 0x00;

            Pid_0x01_2 = (byte) 0x00;

            Pid_0x01_4_to_n = ByteArrayUtil.hexStringToBytes(id);

            Pid_0x01_3 = (byte) (Pid_0x01_4_to_n.length * 8);

            return this;
        }
    }
}
